<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="google-site-verification" content="xBT4GhYoi5qRD5tr338pgPM5OWHHIDR6mNg1a3euekI" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="keyword"  content="Tooi">
    <link rel="shortcut icon" href="/img/favicon.ico">

    <title>
        
        消息队列 &amp; RabbitMQ - Tooi的博客 | Tooi-Blog
        
    </title>

    <!-- Custom CSS -->
    <link rel="stylesheet" href="/css/aircloud.css">
    <link rel="stylesheet" href="/css/gitment.css">
    <!--<link rel="stylesheet" href="https://imsun.github.io/gitment/style/default.css">-->
    <link href="//at.alicdn.com/t/font_620856_pl6z7sid89qkt9.css" rel="stylesheet" type="text/css">
    <!-- ga & ba script hoook -->
    <script></script>
</head>

<body>

<div class="site-nav-toggle" id="site-nav-toggle">
    <button>
        <span class="btn-bar"></span>
        <span class="btn-bar"></span>
        <span class="btn-bar"></span>
    </button>
</div>

<div class="index-about">
    <i> 瞄准月亮。 </i>
</div>

<div class="index-container">
    
    <div class="index-left">
        
<div class="nav" id="nav">
    <div class="avatar-name">
        <div class="avatar ">
            <img src="/img/avatar.jpg" />
        </div>
        <div class="name">
            <i>Tooi6</i>
        </div>
    </div>
    <div class="contents" id="nav-content">
        <ul>
            <li >
                <a href="/">
                    <i class="iconfont icon-shouye1"></i>
                    <span>主页</span>
                </a>
            </li>
            <li >
                <a href="/tags">
                    <i class="iconfont icon-biaoqian1"></i>
                    <span>标签</span>
                </a>
            </li>
            <li >
                <a href="/archives">
                    <i class="iconfont icon-guidang2"></i>
                    <span>存档</span>
                </a>
            </li>
            <li >
                <a href="/about/">
                    <i class="iconfont icon-guanyu2"></i>
                    <span>关于</span>
                </a>
            </li>
            
            <li>
                <a id="search">
                    <i class="iconfont icon-sousuo1"></i>
                    <span>搜索</span>
                </a>
            </li>
            
        </ul>
    </div>
    
        <div id="toc" class="toc-article">
    <ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#简介"><span class="toc-text">简介</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#什么是MQ？"><span class="toc-text">什么是MQ？</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#为什么使用MQ？"><span class="toc-text">为什么使用MQ？</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#使用MQ带来的问题"><span class="toc-text">使用MQ带来的问题</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#MQ框架"><span class="toc-text">MQ框架</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#RabbitMQ的概念"><span class="toc-text">RabbitMQ的概念</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#官网"><span class="toc-text">官网</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#RabbitMQ-使用步骤"><span class="toc-text">RabbitMQ 使用步骤</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#安装RabbitMQ"><span class="toc-text">安装RabbitMQ</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#使用-Docker-安装"><span class="toc-text">使用 Docker 安装</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DEMO"><span class="toc-text">DEMO</span></a></li></ol>
</div>
    
</div>


<div class="search-field" id="search-field">
    <div class="search-container">
        <div class="search-input">
            <span id="esc-search"> <i class="icon-fanhui iconfont"></i></span>
            <input id="search-input"/>
            <span id="begin-search">搜索</span>
        </div>
        <div class="search-result-container" id="search-result-container">

        </div>
    </div>
</div>

        <div class="index-about-mobile">
            <i> 瞄准月亮。 </i>
        </div>
    </div>
    
    <div class="index-middle">
        <!-- Main Content -->
        


<div class="post-container">
    <div class="post-title">
        消息队列 &amp; RabbitMQ
    </div>

    <div class="post-meta">
        <span class="attr">发布于：<span>2019-12-18 23:00:36</span></span>
        
        <span class="attr">标签：/
        
        <a class="tag" href="/tags/#消息队列" title="消息队列">消息队列</a>
        <span>/</span>
        
        <a class="tag" href="/tags/#RabbitMQ" title="RabbitMQ">RabbitMQ</a>
        <span>/</span>
        
        
        </span>
        <span class="attr">访问：<span id="busuanzi_value_page_pv"></span>
</span>
</span>
    </div>
    <div class="post-content ">
        <h3 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h3><h4 id="什么是MQ？"><a href="#什么是MQ？" class="headerlink" title="什么是MQ？"></a>什么是MQ？</h4><blockquote>
<p>Message Queue（MQ），消息队列中间件。消息队列就是在消息传输过程中保存消息的容器。消息队列是分布式系统中重要的组件，<strong>使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。</strong>  </p>
</blockquote>
<h4 id="为什么使用MQ？"><a href="#为什么使用MQ？" class="headerlink" title="为什么使用MQ？"></a>为什么使用MQ？</h4><ul>
<li><strong>提高系统响应速度</strong>  <blockquote>
<p>使用了消息队列，生产者一方，把消息往队列里一扔，就可以立马返回，响应用户了。无需等待处理结果</p>
</blockquote>
</li>
<li><strong>提高系统稳定性</strong><blockquote>
<p>考虑电商系统下订单，发送数据给生产系统的情况。电商系统和生产系统之间的网络有可能掉线，生产系统可能会因维护等原因暂停服务。如果不使用消息队列，电商系统数据发布出去，顾客无法下单，影响业务开展。两个系统间不应该如此紧密耦合。应该通过消息队列解耦。同时让系统更健壮、稳定。  </p>
</blockquote>
</li>
<li><strong>降低系统耦合性</strong><br><img src="https://note.youdao.com/yws/api/personal/file/A7176E3B46CC43D88753827F3A2F30D0?method=download&shareKey=726b280fbca9438a4ff3fcc180705236" alt="image"><blockquote>
<p>消息队列使利用发布-订阅模式工作，消息发送者（生产者）发布消息，一个或多个消息接受者（消费者）订阅消息。 <strong>可以看到消息发送者（生产者）和消息接受者（消费者）之间没有直接耦合。</strong></p>
</blockquote>
</li>
</ul>
<h4 id="使用MQ带来的问题"><a href="#使用MQ带来的问题" class="headerlink" title="使用MQ带来的问题"></a>使用MQ带来的问题</h4><ul>
<li><strong>系统可用性降低</strong>   <blockquote>
<p>需要考虑消息队列挂掉的情况。  </p>
</blockquote>
</li>
<li><strong>系统复杂性提高</strong><blockquote>
<p>需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题！  </p>
</blockquote>
</li>
<li><strong>一致性问题</strong><blockquote>
<p>消息队列带来的异步确实可以提高系统响应速度。但是，万一消息的真正消费者并没有正确消费消息怎么办？这样就会导致数据不一致的情况了!</p>
</blockquote>
</li>
</ul>
<h4 id="MQ框架"><a href="#MQ框架" class="headerlink" title="MQ框架"></a>MQ框架</h4><blockquote>
<p>MQ框架非常之多，比较流行的有<strong>RabbitMq、ActiveMq、ZeroMq、kafka</strong>，以及阿里开源的<strong>RocketMQ</strong>  </p>
</blockquote>
<h4 id="RabbitMQ的概念"><a href="#RabbitMQ的概念" class="headerlink" title="RabbitMQ的概念"></a>RabbitMQ的概念</h4><h4 id="官网"><a href="#官网" class="headerlink" title="官网"></a>官网</h4><blockquote>
<p><a href="https://www.rabbitmq.com/" target="_blank" rel="noopener">https://www.rabbitmq.com/</a></p>
</blockquote>
<ul>
<li><p><strong>生成者和消费者</strong>  </p>
<blockquote>
<p>Producer：消息的生产者<br>Consumer：消息的消费者  </p>
</blockquote>
</li>
<li><p><strong>Queue</strong>  </p>
<blockquote>
<p><strong>消息队列</strong>，提供了 <strong>FIFO</strong> 的处理机制，具有缓存消息的能力。RabbitMQ中，队列消息可以设置为持久化，临时或者自动删除。<br>设置为<strong>持久化的队列</strong>，Queue中的消息会在Server本地硬盘存储一份，防止系统Crash，数据丢失<br>设置为<strong>临时队列</strong>，Queue 中的数据在系统重启之后就会丢失<br>设置为<strong>自动删除的队列</strong>，当不存在用户连接到 Server，队列中的数据会被自动删除  </p>
</blockquote>
</li>
<li><p><strong>ExChange</strong>  </p>
<blockquote>
<p>Exchange 类似于数据通信网络中的<strong>交换机</strong>，提供消息路由策略。RabbitMQ 中，Producer 不是通过信道直接将消息发送给 Queue，而是<strong>先发送给 ExChange。一个 ExChange 可以和多个 Queue 进行绑定</strong>，Producer 在传递消息的时候，会传递一个 <strong>ROUTING_KEY</strong>，ExChange 会根据这个 ROUTING_KEY 按照特定的路由算法，将消息路由给指定的 Queue。和 Queue 一样，ExChange 也可设置为持久化，临时或者自动删除  </p>
</blockquote>
</li>
<li><p><strong>ExChange 的 4 种类型</strong>   </p>
<blockquote>
<p><strong>direct（默认）</strong>：直接交换器，工作方式类似于单播，ExChange 会将消息发送完全匹配 ROUTING_KEY 的 Queue（key 就等于 queue）<br><img src="https://note.youdao.com/yws/api/personal/file/83D7CC27F09F4F39BE14CE53B1F293A3?method=download&shareKey=5c8e155a5935132f597821215977cf19" alt="image"></p>
</blockquote>
</li>
</ul>
<blockquote>
<p><strong>fanout</strong>：广播是式交换器，不管消息的 ROUTING_KEY 设置为什么，ExChange 都会将消息转发给所有绑定的 Queue（无视 key，给所有的 queue 都来一份）<br><img src="https://note.youdao.com/yws/api/personal/file/9CDC7E6BDDFE45499C54B177D2D2C94E?method=download&shareKey=25eb726db6b552ef8e0bd0be9dc50b2a" alt="image"></p>
</blockquote>
<blockquote>
<p><strong>topic</strong>：主题交换器，工作方式类似于组播，ExChange 会将消息转发和 ROUTING_KEY 匹配模式相同的所有队列（key 可以用“宽字符”模糊匹配 queue），比如，ROUTING_KEY 为 user.stock 的 Message 会转发给绑定匹配模式为 * .stock,user.stock， * . * 和 #.user.stock.# 的队列。（ * 表是匹配一个任意词组，# 表示匹配 0 个或多个词组）<br><img src="https://note.youdao.com/yws/api/personal/file/2D67799D2A0A43709CEB2F54ECEFC146?method=download&shareKey=191277cdf1694c234117df6cf9104176" alt="image"></p>
</blockquote>
<blockquote>
<p><strong>headers(不推荐)</strong>：消息体的 header 匹配，无视 key，通过查看消息的头部元数据来决定发给那个 queue（AMQP 头部元数据非常丰富而且可以自定义）。<strong>headers 类型的交换器性能会很差，而且也不实用，基本上不会看到它的存在</strong>  </p>
</blockquote>
<ul>
<li><p><strong>Binding</strong>  </p>
<blockquote>
<p>所谓绑定就是将一个特定的 ExChange 和一个特定的 Queue 绑定起来。ExChange 和 Queue 的绑定可以是多对多的关系</p>
</blockquote>
</li>
<li><p><strong>Virtual Host</strong>  </p>
<blockquote>
<p><strong>在 RabbitMQ Server 上可以创建多个虚拟的 Message Broker</strong>，又叫做 Virtual Hosts (vhosts)。每一个 vhost 本质上是一个 mini-rabbitmq server，分别管理各自的 ExChange，和 bindings。vhost 相当于物理的 Server，可以为不同 app 提供边界隔离，使得应用安全的运行在不同的 vhost 实例上，相互之间不会干扰。Producer 和 Consumer 连接 rabbit server 需要指定一个 vhost  </p>
</blockquote>
</li>
</ul>
<h4 id="RabbitMQ-使用步骤"><a href="#RabbitMQ-使用步骤" class="headerlink" title="RabbitMQ 使用步骤"></a>RabbitMQ 使用步骤</h4><ul>
<li>客户端连接到消息队列服务器，打开一个 Channel。  </li>
<li>客户端声明一个 ExChange，并设置相关属性。  </li>
<li>客户端声明一个 Queue，并设置相关属性。  </li>
<li>客户端使用 Routing Key，在 ExChange 和 Queue 之间建立好绑定关系。  </li>
<li>客户端投递消息到 ExChange。  </li>
<li>ExChange 接收到消息后，就根据消息的key和已经设置的binding，进行消息路由，将消息投递到一个或多个队列里   </li>
</ul>
<h3 id="安装RabbitMQ"><a href="#安装RabbitMQ" class="headerlink" title="安装RabbitMQ"></a>安装RabbitMQ</h3><h4 id="使用-Docker-安装"><a href="#使用-Docker-安装" class="headerlink" title="使用 Docker 安装"></a>使用 Docker 安装</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">## docker-compose.yml 文件</span><br><span class="line">version: &apos;3.1&apos;</span><br><span class="line">services:</span><br><span class="line">  rabbitmq:</span><br><span class="line">    restart: always</span><br><span class="line">    image: rabbitmq:management</span><br><span class="line">    container_name: rabbitmq</span><br><span class="line">    ports:</span><br><span class="line">      - 5672:5672</span><br><span class="line">      - 15672:15672</span><br><span class="line">    environment:</span><br><span class="line">      TZ: Asia/Shanghai</span><br><span class="line">      RABBITMQ_DEFAULT_USER: rabbit</span><br><span class="line">      RABBITMQ_DEFAULT_PASS: 123456</span><br><span class="line">    volumes:</span><br><span class="line">      - ./data:/var/lib/rabbitmq</span><br><span class="line">##</span><br><span class="line"></span><br><span class="line"># 安装完成后访问 ip:15672</span><br></pre></td></tr></table></figure>

<h3 id="DEMO"><a href="#DEMO" class="headerlink" title="DEMO"></a>DEMO</h3><blockquote>
<p>官网提供的demo：<a href="https://www.rabbitmq.com/getstarted.html" target="_blank" rel="noopener">https://www.rabbitmq.com/getstarted.html</a><br>下面例子为 topic 模式下使用 Spring Boot 整合 RabbitMQ，详细查看官方</p>
</blockquote>
<ul>
<li><strong>导入依赖</strong></li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&lt;dependency&gt;</span><br><span class="line">    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;spring-boot-starter-amqp&lt;/artifactId&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">    &lt;groupId&gt;org.springframework.amqp&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;spring-rabbit-test&lt;/artifactId&gt;</span><br><span class="line">    &lt;scope&gt;test&lt;/scope&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></figure>
<ul>
<li><strong>application.yml配置RabbitMQ</strong></li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">spring:</span><br><span class="line">  profiles:</span><br><span class="line">    active: usage_message</span><br><span class="line">  rabbitmq:</span><br><span class="line">    host: ip</span><br><span class="line">    port: 5672</span><br><span class="line"></span><br><span class="line">logging:</span><br><span class="line">  level:</span><br><span class="line">    org: ERROR</span><br><span class="line"></span><br><span class="line">tutorial:</span><br><span class="line">  client:</span><br><span class="line">    duration: 10000</span><br></pre></td></tr></table></figure>

<ul>
<li><strong>创建配置类 Tut5Config</strong></li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line">@Profile(&#123;&quot;tut5&quot;,&quot;topics&quot;&#125;)</span><br><span class="line">@Configuration</span><br><span class="line">public class Tut5Config &#123;</span><br><span class="line"></span><br><span class="line">    @Bean</span><br><span class="line">    public TopicExchange topic() &#123;</span><br><span class="line">        return new TopicExchange(&quot;tut.topic&quot;);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Profile(&quot;receiver&quot;)</span><br><span class="line">    private static class ReceiverConfig &#123;</span><br><span class="line"></span><br><span class="line">        @Bean</span><br><span class="line">        public Tut5Receiver receiver() &#123;</span><br><span class="line">            return new Tut5Receiver();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        @Bean</span><br><span class="line">        public Queue autoDeleteQueue1() &#123;</span><br><span class="line">            return new AnonymousQueue();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        @Bean</span><br><span class="line">        public Queue autoDeleteQueue2() &#123;</span><br><span class="line">            return new AnonymousQueue();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        @Bean</span><br><span class="line">        public Binding binding1a(TopicExchange topic,</span><br><span class="line">                                 Queue autoDeleteQueue1) &#123;</span><br><span class="line">            return BindingBuilder.bind(autoDeleteQueue1)</span><br><span class="line">                    .to(topic)</span><br><span class="line">                    .with(&quot;*.orange.*&quot;);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        @Bean</span><br><span class="line">        public Binding binding1b(TopicExchange topic,</span><br><span class="line">                                 Queue autoDeleteQueue1) &#123;</span><br><span class="line">            return BindingBuilder.bind(autoDeleteQueue1)</span><br><span class="line">                    .to(topic)</span><br><span class="line">                    .with(&quot;*.*.rabbit&quot;);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        @Bean</span><br><span class="line">        public Binding binding2a(TopicExchange topic,</span><br><span class="line">                                 Queue autoDeleteQueue2) &#123;</span><br><span class="line">            return BindingBuilder.bind(autoDeleteQueue2)</span><br><span class="line">                    .to(topic)</span><br><span class="line">                    .with(&quot;lazy.#&quot;);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Profile(&quot;sender&quot;)</span><br><span class="line">    @Bean</span><br><span class="line">    public Tut5Sender sender() &#123;</span><br><span class="line">        return new Tut5Sender();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><strong>生成者类 Tut5Sender</strong></li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">import org.springframework.amqp.core.TopicExchange;</span><br><span class="line">import org.springframework.amqp.rabbit.core.RabbitTemplate;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line">import org.springframework.scheduling.annotation.Scheduled;</span><br><span class="line">import java.util.concurrent.atomic.AtomicInteger;</span><br><span class="line"></span><br><span class="line">public class Tut5Sender &#123;</span><br><span class="line"></span><br><span class="line">    @Autowired</span><br><span class="line">    private RabbitTemplate template;</span><br><span class="line"></span><br><span class="line">    @Autowired</span><br><span class="line">    private TopicExchange topic;</span><br><span class="line"></span><br><span class="line">    AtomicInteger index = new AtomicInteger(0);</span><br><span class="line"></span><br><span class="line">    AtomicInteger count = new AtomicInteger(0);</span><br><span class="line"></span><br><span class="line">    private final String[] keys = &#123;&quot;quick.orange.rabbit&quot;, &quot;lazy.orange.elephant&quot;, &quot;quick.orange.fox&quot;,</span><br><span class="line">            &quot;lazy.brown.fox&quot;, &quot;lazy.pink.rabbit&quot;, &quot;quick.brown.fox&quot;&#125;;</span><br><span class="line"></span><br><span class="line">    @Scheduled(fixedDelay = 1000, initialDelay = 500)</span><br><span class="line">    public void send() &#123;</span><br><span class="line">        StringBuilder builder = new StringBuilder(&quot;Hello to &quot;);</span><br><span class="line">        if (this.index.incrementAndGet() == keys.length) &#123;</span><br><span class="line">            this.index.set(0);</span><br><span class="line">        &#125;</span><br><span class="line">        String key = keys[this.index.get()];</span><br><span class="line">        builder.append(key).append(&apos; &apos;);</span><br><span class="line">        builder.append(this.count.incrementAndGet());</span><br><span class="line">        String message = builder.toString();</span><br><span class="line">        template.convertAndSend(topic.getName(), key, message);</span><br><span class="line">        System.out.println(&quot; [x] Sent &apos;&quot; + message + &quot;&apos;&quot;);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><strong>消费者类 Tut5Receiver</strong></li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">import org.springframework.amqp.rabbit.annotation.RabbitListener;</span><br><span class="line">import org.springframework.util.StopWatch;</span><br><span class="line"></span><br><span class="line">public class Tut5Receiver &#123;</span><br><span class="line"></span><br><span class="line">    @RabbitListener(queues = &quot;#&#123;autoDeleteQueue1.name&#125;&quot;)</span><br><span class="line">    public void receive1(String in) throws InterruptedException &#123;</span><br><span class="line">        receive(in, 1);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @RabbitListener(queues = &quot;#&#123;autoDeleteQueue2.name&#125;&quot;)</span><br><span class="line">    public void receive2(String in) throws InterruptedException &#123;</span><br><span class="line">        receive(in, 2);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void receive(String in, int receiver) throws</span><br><span class="line">            InterruptedException &#123;</span><br><span class="line">        StopWatch watch = new StopWatch();</span><br><span class="line">        watch.start();</span><br><span class="line">        System.out.println(&quot;instance &quot; + receiver + &quot; [x] Received &apos;&quot;</span><br><span class="line">                + in + &quot;&apos;&quot;);</span><br><span class="line">        doWork(in);</span><br><span class="line">        watch.stop();</span><br><span class="line">        System.out.println(&quot;instance &quot; + receiver + &quot; [x] Done in &quot;</span><br><span class="line">                + watch.getTotalTimeSeconds() + &quot;s&quot;);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    private void doWork(String in) throws InterruptedException &#123;</span><br><span class="line">        for (char ch : in.toCharArray()) &#123;</span><br><span class="line">            if (ch == &apos;.&apos;) &#123;</span><br><span class="line">                Thread.sleep(1000);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


        
            <div class="donate-container">
    <div class="donate-button">
        <button id="donate-button">赞赏</button>
    </div>
    <div class="donate-img-container hide" id="donate-img-container">
        <img id="donate-img" src="" data-src="/img/donate.png">
        <p> 感谢鼓励 </p>
    </div>
</div>
        
        <br />
        <div id="comment-container">
        </div>
        <div id="disqus_thread"></div>

        <div id="lv-container">
        </div>

    </div>
</div>

    </div>
</div>


<footer class="footer">
    <ul class="list-inline text-center">
        
        

        

        

        
        <li>
            <a target="_blank"  href="https://github.com/Tooi6">
                            <span class="fa-stack fa-lg">
                                <i class="iconfont icon-github"></i>
                            </span>
            </a>
        </li>
        

        

    </ul>
    
    <p>
        <span>/</span>
        
        <span><a href="https://github.com/Tooi6" target="_blank" rel="noopener">Tooi6</a></span>
        <span>/</span>
        
        <span><a href="#">Tooi-Blog</a></span>
        <span>/</span>
        
        <span><a href="#">It helps SEO</a></span>
        <span>/</span>
        
    </p>
    
    <p>
        <span id="busuanzi_container_site_pv">
            <span id="busuanzi_value_site_pv"></span>PV
        </span>
        <span id="busuanzi_container_site_uv">
            <span id="busuanzi_value_site_uv"></span>UV
        </span>
        Created By <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>  Theme <a href="https://github.com/aircloud/hexo-theme-aircloud" target="_blank" rel="noopener">AirCloud</a></p>
</footer>




</body>

<script>
    // We expose some of the variables needed by the front end
    window.hexo_search_path = "search.json"
    window.hexo_root = "/"
    window.isPost = true
</script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="/js/index.js"></script>
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>




</html>
